﻿using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using YunSpace.Data;
using YunSpace.Domain.Entity.OrderFlowManage;
using YunSpace.Domain.IRepository.OrderFlowManage;
using YunSpace.Domain.ViewModel.OrderFlowManage;
using YunSpace.Repository.OrderFlowManage;

namespace YunSpace.Application.OrderFlowManage
{
    /// <summary>
    /// 客户订单任务表(JOB)
    /// </summary>
    public class ClientOrderJobApp
    {
        private IClientOrderRepository orderService = new ClientOrderRepository();
        private ICheckRecordRepository recordService = new CheckRecordRepository();

        /// <summary>
        /// 获取所有有效的“需求订单”
        /// </summary>
        private List<WorkFlowDetailJobOutput> GetAllDemandOrder(string workFormName) {
            var result = new List<WorkFlowDetailJobOutput>();

            var sqlStr = $@"SELECT SCO.F_Id OrderId, 
		                            SCO.F_OrderState, 
		                            SCO.F_OrderStateProcess, 
		                            SWFD.F_WorkFlowId,
		                            SWF.F_WorkFlowName, 
		                            SWFD.F_StepName, 
		                            SWFD.F_WorkFlowNo,
		                            SWFD.F_TimeOutTip,
		                            SWFD.F_IsFishTime,
		                            SWFD.F_WorkHours,
		                            SWFD.F_TimeOutOpreation,
		                            SWFD.F_OpreationType,
		                            SWFD.F_OpreationUserId, 
		                            SWFD.F_OpreationStrategy, 
		                            SWFD.F_ReturnStrategy,
		                            SWFD.F_MessageSend,
		                            SWFD.F_CcUserId
                        FROM Site_Client_Order SCO 
                        LEFT JOIN Sys_WorkFlow SWF ON SCO.F_WorkFormId = SWF.F_WorkFormId AND SWF.F_DeleteMark IS NULL
                        LEFT JOIN Sys_WorkFlowDetail SWFD ON SWF.F_Id = SWFD.F_WorkFlowId AND SCO.F_OrderState = SWFD.F_WorkFlowNo
                        WHERE SCO.F_State = 1 AND SCO.F_OrderEnvironment = 1 AND SCO.F_WorkFormId='{ workFormName }' AND SCO.F_OrderState IN (1,2,3,4,5,6) AND SCO.F_OrderStateProcess IN(-1,0)
                        ORDER BY SCO.F_Id";

            using (var db = new RepositoryBase())
            {
                return db.FindList<WorkFlowDetailJobOutput>(sqlStr);
            }
        }

        /// <summary>
        /// 获取指定审核记录
        /// </summary>
        private List<CheckRecordEntity> GetAllCheckRecord(string orderId, int? currentState) {
            var sqlStr = $@"SELECT * FROM Sys_CheckRecord SCR 
                                WHERE SCR.F_ApplyType = { currentState } AND SCR.F_OrderId = '{ orderId }'";

            var records = recordService.FindList(sqlStr);

            return records;
        }

        /// <summary>
        /// 跳转下一流程
        /// </summary>
        /// <param name="orderId"></param>
        /// <param name="currentState"></param>
        private void SettingNextDemandOrderState(string orderId, int? currentState)
        {
            var orderEntity = orderService.FindEntity(orderId);
            if (orderEntity != null)
            {
                orderEntity.F_OrderState = currentState + 1;
                orderEntity.F_OrderStateProcess = -1;
                orderEntity.Modify(orderId);
                orderService.Update(orderEntity);
            }
        }

        /// <summary>
        /// 返回上一流程
        /// </summary>
        /// <param name="orderId"></param>
        /// <param name="currentState"></param>
        private void SettingPrevDemandOrderState(string orderId, int? currentState)
        {
            var orderEntity = orderService.FindEntity(orderId);
            if (orderEntity != null)
            {
                orderEntity.F_OrderState = currentState - 1;
                orderEntity.F_OrderStateProcess = -1;
                orderEntity.Modify(orderId);
                orderService.Update(orderEntity);
            }
        }

        /// <summary>
        /// 返回首流程
        /// </summary>
        /// <param name="orderId"></param>
        /// <param name="currentState"></param>
        private void SettingFirstDemandOrderState(string orderId)
        {
            var orderEntity = orderService.FindEntity(orderId);
            if (orderEntity != null)
            {
                orderEntity.F_OrderState = 1;
                orderEntity.F_OrderStateProcess = -1;
                orderEntity.Modify(orderId);
                orderService.Update(orderEntity);
            }
        }

        /// <summary>
        /// 获取待处理人列表
        /// </summary>
        private List<string> GetUserId(string userIds) {
            var result = new List<string>();
            if (userIds.Contains(','))
            {
                result = userIds.Split(',').ToList();
            }
            else {
                result.Add(userIds);
            }
            return result;
        }

        /// <summary>
        /// 设置三种发送类型
        /// </summary>
        /// <param name="opType"></param>
        /// <param name="emailAction"></param>
        /// <param name="smsAction"></param>
        /// <param name="sysAction"></param>
        private void SendByType(string opType, Action emailAction, Action smsAction, Action sysAction) {
            /*处理方式0：邮件，1：短信，2：站内通知*/
            if (!string.IsNullOrEmpty(opType))
            {
                if (opType.Contains("0")) emailAction();
                else if (opType.Contains("1")) smsAction();
                else if (opType.Contains("2")) sysAction();
            }
        }

        /// <summary>
        /// 执行 “需求订单” 逻辑
        /// </summary>
        /// <param name="workFormName">流程名称</param>
        public void ExecuteDemandOrder(string workFormName = "lc1002") {
            // 获取所有需求订单
            var allOrder = GetAllDemandOrder(workFormName);
            if (allOrder.Any())
            {
                allOrder.ForEach(order => {
                    //`F_WorkFlowId` VARCHAR(50) NOT NULL COMMENT '流程编号',
                    //`F_WorkFlowNo` INT(11) NULL DEFAULT NULL COMMENT '流程序号',
                    //`F_StepName` VARCHAR(50) NULL DEFAULT NULL COMMENT '步骤名称',
                    var orderId = order.OrderId;
                    var state = order.F_OrderState;                     /*订单状态*/

                    var checkRecords = GetAllCheckRecord(orderId, state);
                    // 有审核记录
                    if (checkRecords.Any())
                    {
                        var unRecords = checkRecords.Where(p => p.F_State == null);
                        var passRecords = checkRecords.Where(p => p.F_State == 1);
                        var ngRecords = checkRecords.Where(p => p.F_State == 0);

                        #region 1. 审核处理
                        var opreationtype = order.F_OpreationType;                      /*处理方式0：邮件，1：短信，2：站内通知*/
                        var opreationuserid = GetUserId(order.F_OpreationUserId);       /*处理人编号*/
                        var opreationstrategy = order.F_OpreationStrategy;              /*处理策略0:所有人必须同意，1：一人同意即可*/
                        var msgsend = order.F_MessageSend;                              /*消息发送方式0：邮件，1：短信，2：站内通知*/
                        var ccuserId = GetUserId(order.F_CcUserId);                     /*抄送人编号*/
                        if (opreationstrategy == 0 && passRecords.Count() > 0)  /*一人同意即可*/
                        {
                            // 更新流程状态
                            SettingNextDemandOrderState(orderId, state);
                        }
                        else if (opreationstrategy == 1 && passRecords.Count() == checkRecords.Count) /*所有人必须同意*/
                        {
                            // 更新流程状态
                            SettingNextDemandOrderState(orderId, state);
                        }
                        #endregion

                        #region 2.退回审核处理
                        var returnstrategy = order.F_ReturnStrategy;        /*退回策略0：一人退回全部退回，1：所有人退回全部退回*/
                        var returntype = order.F_ReturnType;                /*退回类型0：退回前一步，1：退回到初试状态*/
                        if (returnstrategy == 0 && ngRecords.Count() > 0)   /*一人退回全部退回*/
                        {
                            if (returntype == 0)        /*退回前一步*/
                            {
                                // 更新流程状态
                                SettingPrevDemandOrderState(orderId, state);
                            }
                            else if (returntype == 1)   /*退回到初试状态*/
                            {
                                // 更新流程状态
                                SettingFirstDemandOrderState(orderId);
                            }
                        }
                        else if (returnstrategy == 1 && ngRecords.Count() == checkRecords.Count) /*所有人退回全部退回*/
                        {
                            if (returntype == 0)        /*退回前一步*/
                            {
                                // 更新流程状态
                                SettingPrevDemandOrderState(orderId, state);
                            }
                            else if (returntype == 1)   /*退回到初试状态*/
                            {
                                // 更新流程状态
                                SettingFirstDemandOrderState(orderId);
                            }
                        }
                        #endregion

                        #region 3. 超时审核处理
                        // 处理超时逻辑
                        var timeoutopreation = order.F_TimeOutOpreation;    /*超时处理0:不处理，1：处理*/
                        var timeout = order.F_TimeOutTip;                   /*超期提示0:不提示，1：提示*/
                        var isfishtime = order.F_IsFishTime;                /*指定完成时间0:不指定，1：指定*/
                        var WorkHours = order.F_WorkHours;                  /*工时(小时)*/
                        // 超时处理和超期提示 都操作时
                        if (timeoutopreation == 1 && timeout == 1 && isfishtime == 1)
                        {
                            // 超时处理（如何限定任务的次数）
                        }
                        #endregion

                    }

                });
            }
        }

        public void ExecuteCheckOrder()
        {
            string sql = $@"";
        }
    }
}
